/*
 *   Copyright 2012, Thomas Kerber
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package milk.skimmed;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;

/**
 * Extracts a mod.
 * 
 * Some files get copied directly into the minecraft folder (typically
 * resources or external libraries). These are assumed to be non-conflicting
 * and won't be (de)activatable.
 * 
 * Jarps get added to the jarp list and are generated out of loose class files.
 * @author Thomas Kerber
 * @version 1.0.0
 */
public class Extracter{
    
    /**
     * The default extraction instructions.
     */
    public static final Class<? extends ExtractionInstructions>
            DEFAULT_EXTRACT = StandardExtractionInstructions.class;
    
    /**
     * Extracts.
     * 
     * @param extractFrom Where to extract from.
     * @param minecraftRoot Minecrafts root directory.
     * @param name The name of the file to extract from.
     * @throws IOException
     * @throws MissingReqsException
     */
    public static void extract(File extractFrom, File minecraftRoot,
            String name) throws IOException, MissingReqsException{
        ExtractionInstructions einst = null;
        for(String fname : extractFrom.list()){
            if(fname.startsWith("milk_extract") && fname.endsWith(".class")){
                // Load dynamically and use as an extraction instructions.
                try{
                    Class<?> extrClass = ForceClassLoader.forceLoad(
                            fname.substring(0, fname.length() - 6),
                            new File(extractFrom, fname));
                    einst = (ExtractionInstructions)extrClass.newInstance();
                }
                catch(IOException e){
                    Util.logger.log(Level.WARNING,
                            "Extraction class found, but failed to load.", e);
                }
                catch(InstantiationException e){
                    Util.logger.log(Level.WARNING,
                            "Extraction class found and loaded, but failed " +
                            "to instantiate.", e);
                }
                catch(IllegalAccessException e){
                    Util.logger.log(Level.WARNING,
                            "Extraction class found and loaded, access was " +
                            "denied.", e);
                }
                catch(ClassCastException e){
                    Util.logger.log(Level.WARNING,
                            "Extraction class found and loaded, but does " +
                            "not implement required interfaces.", e);
                }
                break;
            }
        }
        if(einst == null){
            try{
                einst = DEFAULT_EXTRACT.newInstance();
            }
            // Squishy, squishy. These can't happen.
            catch(InstantiationException e){}
            catch(IllegalAccessException e){}
        }
        
        einst.init(extractFrom, minecraftRoot, Skimmed.CONFIG.getJarpList(),
                name);
        
        einst.extractFiles(extractFrom, minecraftRoot);
        File opt = new File(new File(minecraftRoot, "milk"), "opt");
        opt.mkdirs();
        
        File[] jarps = einst.extractJarps(extractFrom);
        for(File f : jarps){
            File outF = new File(opt, f.getName());
            Util.copyFile(f, outF);
            Jarp j = new Jarp(outF);
            Skimmed.CONFIG.addJarp(j);
        }
        
        for(JarpCreationInfo jci : einst.extractClassRoots(
                extractFrom, Skimmed.CONFIG.getJarpList()))
            Skimmed.CONFIG.addJarp(jci.createJarp());
        
        einst.close();
        
    }
}
